import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from "../types"
import xhr from "../core/xhr"
import { buildURL, isAbsoluteURL, combineURL } from "../helpers/url"
import { flattenHeaders } from "../helpers/headers"
import transform from './transform'

export default function dispatchRequest(config: AxiosRequestConfig): AxiosPromise {
    // TODO
    throwIfCancellationRequested(config) // token 已经使用 不发送请求
    processConfig(config)
    return xhr(config).then((res) => {
        return transformResponseData(res)
    }, e => {
        if (e && e.response) {
            e.response = transformResponseData(e.response)
        }
        return Promise.reject(e)
    })
}

// config 参数处理 public
function processConfig(config: AxiosRequestConfig): void {
    config.url = transformURL(config)
    config.data = transform(config.data, config.headers, config.transformRequest)
    config.headers = flattenHeaders(config.headers, config.method!)

}

// 处理 url 和params

export function transformURL(config: AxiosRequestConfig): string {
    let { url, params, paramsSerializer, baseURL } = config
    // 断言 url 不为空
    if (baseURL && !isAbsoluteURL(url!)) {
        url = combineURL(baseURL, url)
    }
    return buildURL(url!, params, paramsSerializer)
}

// 字符串 尝试 转对象 如果是
function transformResponseData(res: AxiosResponse): AxiosResponse {
    res.data = transform(res.data, res.headers, res.config.transformResponse)
    return res
}

// 如果 token 不为空 token 已经使用 发送请求
function throwIfCancellationRequested(config: AxiosRequestConfig): void {
    if (config.cancelToken) {
        config.cancelToken.throwIfRequested()
    }
}